001 /*
002 * Copyright 2004 Stephen J. McConnell.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
013 * implied.
014 *
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 package net.dpml.metro.data;
020
021 import java.util.Arrays;
022
023 import net.dpml.component.Directive;
024
025 import net.dpml.metro.info.PartReference;
026
027 /**
028 * A context descriptor declares the context creation criteria for
029 * the context instance and context entries.
030 *
031 * <p><b>XML</b></p>
032 * <p>A context directive may contain multiple import statements. Each import
033 * statement corresponds to a request for a context value from the container.</p>
034 * <pre>
035 * <context class="<font color="darkred">MyContextClass</font>">
036 * <entry key="<font color="darkred">special</font>">
037 * <import key="<font color="darkred">urn:avalon:classloader</font>"/>
038 * </entry>
039 * <entry key="<font color="darkred">xxx</font>">
040 * <param class="<font color="darkred">MySpecialClass</font>">
041 * <param><font color="darkred">hello</font></param>
042 * <param class="<font color="darkred">java.io.File</font>"><font color="darkred">../lib</font></param>
043 * </param>
044 * </entry>
045 * </context>
046 * </pre>
047 *
048 * @author <a href="http://www.dpml.net">Digital Product Meta Library</a>
049 * @version 1.0.1
050 */
051 public final class ContextDirective extends AbstractDirective
052 {
053 //--------------------------------------------------------------------------
054 // static
055 //--------------------------------------------------------------------------
056
057 /**
058 * Serial version identifier.
059 */
060 static final long serialVersionUID = 1L;
061
062 private static final PartReference[] EMPTY_REFS = new PartReference[0];
063
064 //--------------------------------------------------------------------------
065 // state
066 //--------------------------------------------------------------------------
067
068 /**
069 * The set of entry directives.
070 */
071 private final PartReference[] m_entries;
072
073 /**
074 * The context implementation classname.
075 */
076 private final String m_classname;
077
078 //--------------------------------------------------------------------------
079 // constructors
080 //--------------------------------------------------------------------------
081
082 /**
083 * Creation of a context directive.
084 */
085 public ContextDirective()
086 {
087 this( new PartReference[0] );
088 }
089
090 /**
091 * Creation of a context directive
092 * @param entries the set of entry descriptors
093 */
094 public ContextDirective( final PartReference[] entries )
095 {
096 this( null, entries );
097 }
098
099 /**
100 * Creation of a new file target.
101 * @param classname the context implementation class
102 * @param entries the set of entry descriptors
103 */
104 public ContextDirective( final String classname, final PartReference[] entries )
105 {
106 m_classname = classname;
107 if( entries != null )
108 {
109 for( int i=0; i<entries.length; i++ )
110 {
111 PartReference ref = entries[i];
112 if( null == ref )
113 {
114 throw new NullPointerException( "entry" );
115 }
116 }
117 m_entries = entries;
118 }
119 else
120 {
121 m_entries = EMPTY_REFS;
122 }
123 }
124
125 //--------------------------------------------------------------------------
126 // implementation
127 //--------------------------------------------------------------------------
128
129 /**
130 * Return the classname of the context implementation to use.
131 * @return the classname
132 */
133 public String getClassname()
134 {
135 return m_classname;
136 }
137
138 /**
139 * Return the set of entry directives.
140 * @return the entries
141 */
142 public PartReference[] getDirectives()
143 {
144 return m_entries;
145 }
146
147 /**
148 * Return part reference defining the value for the requested entry.
149 * @param key the context entry key
150 * @return the part reference corresponding to the supplied key or null if the
151 * key is unknown
152 */
153 public PartReference getPartReference( String key )
154 {
155 for( int i = 0; i < m_entries.length; i++ )
156 {
157 PartReference entry = m_entries[ i ];
158 if( entry.getKey().equals( key ) )
159 {
160 return entry;
161 }
162 }
163 return null;
164 }
165
166 /**
167 * Return part defining the value for the requested entry.
168 * @param key the context entry key
169 * @return the part defintion corresponding to the supplied key or null if the
170 * key is unknown
171 */
172 public Directive getPartDirective( String key )
173 {
174 PartReference ref = getPartReference( key );
175 if( null != ref )
176 {
177 return ref.getDirective();
178 }
179 else
180 {
181 return null;
182 }
183 }
184
185 /**
186 * Test if the supplied object is equal to this object.
187 * @param other the object to compare with this instance
188 * @return TRUE if the supplied object is equal to this object
189 */
190 public boolean equals( Object other )
191 {
192 if( !super.equals( other ) )
193 {
194 return false;
195 }
196 else if( !( other instanceof ContextDirective ) )
197 {
198 return false;
199 }
200 else
201 {
202 ContextDirective context = (ContextDirective) other;
203 if( !equals( m_classname, context.m_classname ) )
204 {
205 return false;
206 }
207 else
208 {
209 return Arrays.equals( m_entries, context.m_entries );
210 }
211 }
212 }
213
214 /**
215 * Return the hashcode for the instance.
216 * @return the instance hashcode
217 */
218 public int hashCode()
219 {
220 int hash = super.hashCode();
221 hash ^= hashValue( m_classname );
222 hash ^= hashArray( m_entries );
223 return hash;
224 }
225 }